package cn.hyp.bantang.module.finance.pdf;

import cn.hyp.bantang.module.finance.dal.dataobject.basegs.BaseGsDO;
import cn.hyp.bantang.module.finance.dal.dataobject.baselr.BaseLrDO;
import cn.hyp.bantang.module.finance.dal.dataobject.basexj.BaseXjDO;
import cn.hyp.bantang.module.finance.dal.dataobject.basezcfz.BaseZcfzDO;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.pdfbox.multipdf.Splitter;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
import technology.tabula.ObjectExtractor;
import technology.tabula.Page;
import technology.tabula.RectangularTextContainer;
import technology.tabula.Table;
import technology.tabula.extractors.SpreadsheetExtractionAlgorithm;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class PdfUtils {
    public static final String REGEX_CODE = "公司代码：?(?<code>\\d{6})";
    public static final String REGEX_NAME = "公司简称：?(?<name>[\\u4e00-\\u9fa5]{3,4})";
    public static final String REGEX_DATE = "(\\d{4})\\s*年\\s*(\\d{1,2})\\s*月\\s*(\\d{1,2})\\s*日";
    public static final String HB = "hb";
    public static final String MGS = "mgs";

    public static final String ZCFZ = "zcfz";

    public static final String LR = "lr";

    public static final String XJ = "xj";
    public static final String TYPE_HB_ZCFZ = HB + "_" + ZCFZ;
    public static final String TYPE_MGS_ZCFZ = MGS + "_" + ZCFZ;
    public static final String TYPE_HB_LR = HB + "_" + LR;
    public static final String TYPE_MGS_LR = MGS + "_" + LR;
    public static final String TYPE_HB_XJ = HB + "_" + XJ;
    public static final String TYPE_MGS_XJ = MGS + "_" + XJ;
    public static Finance parseFinanceByReport(String pdfPath,
                                               Map<String, String> zcfzMap,  Map<String, String> lrMap, Map<String, String> xjMap){
        try (PDDocument document = PDDocument.load(new File(pdfPath))) {
            Finance finance = new Finance();
            //文本分离器
            PDFTextStripper pdfTextStripper = new PDFTextStripper();
            //表格算法
            SpreadsheetExtractionAlgorithm sea = new SpreadsheetExtractionAlgorithm();
            //提取器
            ObjectExtractor oe = null;

            Splitter splitter = new Splitter();
            List<PDDocument> pages = splitter.split(document);
            int pageNumber = 1;
            List<Table> tableList = new ArrayList<>();
            boolean parseThree = false;
            List<PDDocument> afterClosePdList = new ArrayList<>();
           //每一页去解析，每一页最多两张表
            for (PDDocument page : pages) {
                String pageText = pdfTextStripper.getText(page);
                //解析公司基本信息
                parseGs(pageText, finance);
                //开始解析三大表
                if (pageText.indexOf("合并资产负债表")>0){
                    parseThree = true;
                }
                if(parseThree){
                    oe = new ObjectExtractor(page);
                    Page pageLua = oe.extract(1);
                    List<Table> tables = sea.extract(pageLua);
                    //解析合并资产负债表
                    if(pageText.indexOf("合并资产负债表")>0){
                        if(tables.size()>0){
                            tableList.add(tables.get(tables.size()-1));
                        }
                    }
                    //可能会有合并权益表
                    tableList.addAll(tables);
                }
                pageNumber++;
                if (pageText.indexOf("合并所有者权益变动表")>0){
                    parseThree = false;
                    break;
                }
            }
            parseThree(tableList, finance, zcfzMap, lrMap, xjMap);
            //关闭
            for (PDDocument page : pages) {
                page.close();
            }
            return finance;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {

        }
        return null;
    }
    public static void parseThree(List<Table> tableList, Finance finance,
                                  Map<String, String> zcfzMap, Map<String, String> lrMap, Map<String, String> xjMap){
        //解析合并资产负债表
        BaseZcfzDO hbZcfz = new BaseZcfzDO();
        //解析母公司资产负债表
        BaseZcfzDO mgsZcfz = new BaseZcfzDO();
        //解析合并利润表
        BaseLrDO hbLr = new BaseLrDO();
        //解析母公司利润表
        BaseLrDO mgsLr = new BaseLrDO();
        //解析合并现金流量表
        BaseXjDO hbXj = new BaseXjDO();
        //解析母公司现金流量表
        BaseXjDO mgsXj = new BaseXjDO();

        finance.setHbZcfz(hbZcfz).setMgsZcfz(mgsZcfz)
                .setHbLr(hbLr).setMgsLr(mgsLr)
                .setHbXj(hbXj).setMgsXj(mgsXj);
        for (Table table: tableList) {
            Map<String, String> tableMap = new LinkedHashMap<String, String>();
            List<List<RectangularTextContainer>> rows = table.getRows();
            for (int j=0;j<rows.size();j++){
                List<RectangularTextContainer> row = rows.get(j);
                //两行的没价值
                if(row.size()<2){
                    break;
                }
                int valueIndex = 1;
                //两个单元格就是 项目 条目
                if(row.size()==2){
                    valueIndex = 1;
                }
                //三个单元格就是 项目 本期 上期
                if(row.size()==3){
                    valueIndex = 1;
                }
                //四个单元格就是 项目 附注 本期 上期
                if(row.size()==4){
                    valueIndex = 2;
                }
                tableMap.put(row.get(0).getText(), row.get(valueIndex).getText());
            }
            if(!hbZcfz.parsed()){
                reflectionToField(tableMap, zcfzMap, hbZcfz);
            }else if(!mgsZcfz.parsed()){
                reflectionToField(tableMap, zcfzMap, mgsZcfz);

            }else if(!hbLr.parsed()){
                reflectionToField(tableMap, lrMap, hbLr);

            }else if(!mgsLr.parsed()){
                reflectionToField(tableMap, lrMap, mgsLr);

            }else if(!hbXj.parsed()){
                reflectionToField(tableMap, xjMap, hbXj);

            }else if(!mgsXj.parsed()){
                reflectionToField(tableMap, xjMap, mgsXj);

            }
            //解析完毕，退出
            if(finance.parsed()){
                return;
            }
        }

    }
    public static void reflectionToField(Map<String, String> tableMap, Map<String, String> dbFieldMap, Object target){
        //实体对象的属性
        Map<String, Field> fieldMap = new LinkedHashMap<>();
        ReflectionUtils.doWithFields(target.getClass(), field->fieldMap.put(field.getName(), field));
       for(String tableKey: tableMap.keySet()){
           String dbFiledName = dbFieldMap.get(tableKey);
           String value = tableMap.get(tableKey);

           if(StringUtils.hasLength(dbFiledName) && StringUtils.hasLength(value)){
               Field field = fieldMap.get(dbFiledName);
               if(field!=null){
                   value = value.replaceAll(",","");
                   BigDecimal bigValue = NumberUtils.toScaledBigDecimal(value);
                   ReflectionUtils.makeAccessible(field);
                   ReflectionUtils.setField(field, target, bigValue);

               }
           }
       }
    }
    /**
     * 解析公司基本信息
     * @param text
     * @param finance
     */
    public static void parseGs(String text, Finance finance){
        BaseGsDO gsDO = finance.getGs();
        if(gsDO==null){
            gsDO = new BaseGsDO();
            finance.setGs(gsDO);
        }
        if(!gsDO.fullCode()){
            Pattern pattern = Pattern.compile(REGEX_CODE);
            Matcher matcher = pattern.matcher(text);
            if(matcher.find()){
                gsDO.setSecCode(matcher.group("code"));
            }
        }
        if(!gsDO.fullName()){
            Pattern pattern = Pattern.compile(REGEX_NAME);
            Matcher matcher = pattern.matcher(text);
            if(matcher.find()){
                gsDO.setSecName(matcher.group("name"));
            }
        }
    }
    public static String regexMatch(List<String> regexList, String text){
        for(String regex: regexList) {
            Pattern pattern = Pattern.compile(regex);
            Matcher matcher = pattern.matcher(text);
            if (matcher.find()) {
                return matcher.group(1);
            }
        }
        return null;
    }
    public static void main(String[] args) throws IOException {
//        String pdfPath = "G:\\code\\labs\\tabula-java\\src\\test\\resources\\technology\\tabula\\mt.PDF";
//        genSubPdfByPage(pdfPath);
//        String gs = "大小约：5389173cm,dana";
//        List<String> list = new ArrayList<>();
//        list.add("大小\\D{3}(\\d)");
//        System.out.println(regexMatch(list, gs));
           String DATE_STRING = "公司代码：600519                                           公司简称：贵州茅台 ";
//           String P_COMM = "公司代码：?(?<code>\\d{6})";
        String P_COMM = "公司简称：?(?<name>[\\u4e00-\\u9fa5]{3,4})";
        Pattern pattern = Pattern.compile(P_COMM);
        Matcher matcher = pattern.matcher(DATE_STRING);
        matcher.find();//必须要有这句
        System.out.printf("\nmatcher.group(0) value:%s", matcher.group("name"));
        System.out.printf("\nmatcher.group(1) value:%s", matcher.group(1));
//        System.out.printf("\nmatcher.group(2) value:%s", matcher.group(2));
//        System.out.printf("\nmatcher.group(3) value:%s", matcher.group(3));
    }

}
